class Article {
  public time = 0;
  public val: number;
  public order: number;
  constructor(val: number, order: number, time?: number) {
    this.val = val;
    this.order = order;
    this.time = typeof time === 'undefined' ? new Date().getTime() : time;
  }
}

class Twitter {
  private tweets: Map<number, Article[]>;
  private followees: Map<number, Set<number>>;
  private order: number = 0;

  constructor() {
    this.tweets = new Map();
    this.followees = new Map();
  }

  postTweet(userId: number, tweetId: number): void {
    const article = new Article(tweetId, ++this.order);
    if (this.tweets.has(userId)) {
      this.tweets.get(userId).push(article);
    } else {
      this.tweets.set(userId, [article]);
    }
  }

  getNewsFeed(userId: number): number[] {
    const ans: Article[] = [];
    const ids = new Set([userId, ...(this.followees.get(userId) || [])]);
    for (let id of ids) {
      if (!this.tweets.has(id)) continue;
      ans.push(...this.tweets.get(id));
    }
    ans.sort((a, b) => b.order - a.order);
    return ans.map(item => item.val).slice(0, 10);
  }

  follow(followerId: number, followeeId: number): void {
    if (followerId === followeeId) return;
    if (this.followees.has(followerId)) {
      this.followees.get(followerId).add(followeeId);
    } else {
      this.followees.set(followerId, new Set([followeeId]));
    }
  }

  unfollow(followerId: number, followeeId: number): void {
    if (followerId !== followeeId && this.followees.has(followerId)) {
      this.followees.get(followerId).delete(followeeId);
    }
  }
}

/**
 * Your Twitter object will be instantiated and called as such:
 * var obj = new Twitter()
 * obj.postTweet(userId,tweetId)
 * var param_2 = obj.getNewsFeed(userId)
 * obj.follow(followerId,followeeId)
 * obj.unfollow(followerId,followeeId)
 */